#include "commsys_mgr.hpp"
#include <iostream>
#include <chrono>
#include "spdlog/spdlog.h"

CommSystemManager& CommSystemManager::getInstance() {
    static CommSystemManager instance;
    return instance;
}

CommSystemManager::~CommSystemManager() {
    stopMonitoring();
    shutdownAll();
}

void CommSystemManager::addInterface(const std::string& name, std::shared_ptr<CommInterface> interface) {
    std::lock_guard<std::mutex> lock(interfacesMutex_);
    interfaces_[name] = std::move(interface);
}

void CommSystemManager::removeInterface(const std::string& name) {
    std::lock_guard<std::mutex> lock(interfacesMutex_);
    auto it = interfaces_.find(name);
    if (it != interfaces_.end()) {
        it->second->shutdown();
        interfaces_.erase(it);
    }
}

std::shared_ptr<CommInterface> CommSystemManager::getInterface(const std::string& name) {
    std::lock_guard<std::mutex> lock(interfacesMutex_);
    auto it = interfaces_.find(name);
    return it != interfaces_.end() ? it->second : nullptr;
}

bool CommSystemManager::initializeAll() {
    std::lock_guard<std::mutex> lock(interfacesMutex_);
    bool allInitialized = true;
    
    for (auto& [name, interface] : interfaces_) {
        if (!interface->initialize()) {
            spdlog::error("Failed to initialize interface:{}",name);
            allInitialized = false;
        }
        else
        {
             spdlog::info("initialize interface:{} sucessful",name);
        }
    }
    
    return allInitialized;
}

void CommSystemManager::shutdownAll() {
    std::lock_guard<std::mutex> lock(interfacesMutex_);
    for (auto& [name, interface] : interfaces_) {
        interface->shutdown();
    }
    printf("Shutdown all interfaces\n");
}

void CommSystemManager::startMonitoring() {
    if (!monitoring_) {
        monitoring_ = true;
        monitorThread_ = std::thread(&CommSystemManager::monitoringThreadFunc, this);
    }
}

void CommSystemManager::stopMonitoring() {
    if (monitoring_) {
        monitoring_ = false;
        if (monitorThread_.joinable()) {
            monitorThread_.join();
        }
    }
}

void CommSystemManager::monitoringThreadFunc() {
    while (monitoring_) {
        {
            std::lock_guard<std::mutex> lock(interfacesMutex_);
            for (auto& [name, interface] : interfaces_) {
                // Monitor the connection status of each interface
                if (!interface->isConnected()) {
                    spdlog::warn("Interface {} is disconnected. Attempting to reconnect...",name);
                    interface->shutdown();
                    interface->initialize();
                }

                // other monitoring logic can be added here
                // ...
            }
        }
        
        std::this_thread::sleep_for(std::chrono::seconds(5));
    }
}